package com.example.materials_management.service;

import com.example.materials_management.entity.ExportInfoEntity;
import com.example.materials_management.entity.MaterialsRemainingInfoEntity;
import com.example.materials_management.repository.ExportInfoRepository;
import com.example.materials_management.repository.MaterialsBasicInfoRepository;
import com.example.materials_management.repository.MaterialsRemainingInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ExportInfoService {
    @Autowired
    ExportInfoRepository exportInfoRepository;
    @Autowired
    MaterialsBasicInfoRepository materialsBasicInfoRepository;
    @Autowired
    MaterialsRemainingInfoRepository materialsRemainingInfoRepository;

    public List<Map<String, Object>> getItems(
            Integer materialId,
            String operateLocation,
            String applicants,
            String operator,
            Integer amountMin,
            Integer amountMax
    ) {
        return exportInfoRepository.findItems(materialId, operateLocation, applicants, operator, amountMin, amountMax);
    }

    @Modifying
    public Map<String, Object> addItems(List<ExportInfoEntity> entities) {
        List<ExportInfoEntity> errors = new ArrayList<>();
        List<ExportInfoEntity> amountErrors = new ArrayList<>();
        List<MaterialsRemainingInfoEntity> materialsRemainingInfoEntities = new ArrayList<>();
        for (ExportInfoEntity entity : entities) {
            Optional<MaterialsRemainingInfoEntity> tmp = materialsRemainingInfoRepository.findById(entity.getMaterialId());
            if (!tmp.isPresent()) errors.add(entity);
            else {
                MaterialsRemainingInfoEntity materialsRemainingInfoEntity = tmp.get();
                int remainingAmount = materialsRemainingInfoEntity.getRemainingAmount();
                if (remainingAmount < entity.getAmount()) amountErrors.add(entity);
                else {
                    materialsRemainingInfoEntity.setRemainingAmount(remainingAmount - entity.getAmount());
                    materialsRemainingInfoEntities.add(materialsRemainingInfoEntity);
                }
            }
        }
        Map<String, Object> res = new HashMap<>();
        if (errors.size() > 0) {
            res.put("Status", "Error");
            res.put("Information", "Material id does not exist");
            res.put("Error Items", errors);
        } else if (amountErrors.size() > 0) {
            res.put("Status", "Error");
            res.put("Information", "Remaining amount is not enough");
            res.put("Error Items", amountErrors);
        } else {
            exportInfoRepository.saveAll(entities);
            materialsRemainingInfoRepository.saveAll(materialsRemainingInfoEntities);
            res.put("Status", "Success");
        }
        return res;
    }

    @Modifying
    public Map<String, Object> modifyItem(Integer id, ExportInfoEntity entity) {
        Optional<ExportInfoEntity> tmp = exportInfoRepository.findById(id);
        Map<String, Object> res = new HashMap<>();
        if (!tmp.isPresent()) {
            res.put("Status", "Error");
            res.put("Information", "Id does not exist");
        } else {
            Optional<MaterialsRemainingInfoEntity> tmpNew = materialsRemainingInfoRepository.findById(entity.getMaterialId());
            if (!tmpNew.isPresent()) {
                res.put("Status", "Error");
                res.put("Information", "Material id does not exist");
            } else {
                MaterialsRemainingInfoEntity materialsRemainingInfoEntityNew = tmpNew.get();
                ExportInfoEntity exportInfoEntityOrigin = tmp.get();
                entity.setId(exportInfoEntityOrigin.getId());
                MaterialsRemainingInfoEntity materialsRemainingInfoEntityOrigin = materialsRemainingInfoRepository.findById(exportInfoEntityOrigin.getMaterialId()).get();
                if (entity.getMaterialId() != exportInfoEntityOrigin.getMaterialId()) {
                    int remainingAmountNew = materialsRemainingInfoEntityNew.getRemainingAmount();
                    int remainingAmountOrigin = materialsRemainingInfoEntityOrigin.getRemainingAmount();
                    if (remainingAmountNew - entity.getAmount() < 0) {
                        res.put("Status", "Error");
                        res.put("Information", "Remaining amount is not enough");
                    } else {
                        materialsRemainingInfoEntityNew.setRemainingAmount(remainingAmountNew - entity.getAmount());
                        materialsRemainingInfoEntityOrigin.setRemainingAmount(remainingAmountOrigin + exportInfoEntityOrigin.getAmount());
                        exportInfoRepository.save(entity);
                        materialsRemainingInfoRepository.save(materialsRemainingInfoEntityNew);
                        materialsRemainingInfoRepository.save(materialsRemainingInfoEntityOrigin);
                        res.put("Status", "Success");
                    }
                } else {
                    int remainingAmount = materialsRemainingInfoEntityNew.getRemainingAmount();
                    if (remainingAmount - entity.getAmount() + exportInfoEntityOrigin.getAmount() < 0) {
                        res.put("Status", "Error");
                        res.put("Information", "Remaining amount is not enough");
                    } else {
                        materialsRemainingInfoEntityNew.setRemainingAmount(remainingAmount - entity.getAmount() + exportInfoEntityOrigin.getAmount());
                        exportInfoRepository.save(entity);
                        materialsRemainingInfoRepository.save(materialsRemainingInfoEntityNew);
                        res.put("Status", "Success");
                    }
                }
            }
        }
        return res;
    }
}
